package com.ehsy.service;

import com.dtflys.forest.annotation.*;
import com.ehsy.common.ResponseVo;
import com.ehsy.model.UserInfo;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author YanZhen_Li
 * @version 1.0
 * @title RequestBodyTest
 * @description
 * @create 2024/6/17 17:26
 */
@Component
@Address(host = "127.0.0.1", port = "8080")
public interface RequestBodyService {
    // ? -------------------------表单请求-------------------
    /**
     * 默认body格式为 application/x-www-form-urlencoded，即以表单形式序列化数据
     */
    @Post("/test/request/json/formBody")
    ResponseVo<Map<String, Object>> test01(@Body("username") String username, @Body("password") String password);

    /**
     * contentType属性设置为 application/x-www-form-urlencoded 即为表单格式，
     * 当然不设置的时候默认值也为 application/x-www-form-urlencoded， 也同样是表单格式。
     * 在 @Body 注解的 value 属性中设置的名称为表单项的 key 名，
     * 而注解所修饰的参数值即为表单项的值，它可以为任何类型，不过最终都会转换为字符串进行传输。
     */
    @Post(
            url = "/test/request/json/formBody",
            contentType = "application/x-www-form-urlencoded"
    )
    ResponseVo<Map<String, Object>> test02(@Body("key1") String value1,  @Body("key2") Integer value2, @Body("key3") Long value3);

    /**
     * contentType 属性不设置默认为 application/x-www-form-urlencoded
     * 要以对象作为表达传输项时，其 @Body 注解的 value 名称不能设置
     */
    @Post("/test/request/json/formBody")
    ResponseVo<UserInfo> test03(@Body UserInfo user);

    // ? -------------------------json请求-------------------
    /**
     * 被@JSONBody注解修饰的参数会根据其类型被自定解析为JSON字符串
     * 使用@JSONBody注解时可以省略 contentType = "application/json"属性设置
     */
    @Post("/test/request/json/body")
    ResponseVo<UserInfo> test04(@JSONBody UserInfo user);


    /**
     * 按键值对分别修饰不同的参数
     * 这时每个参数前的 @JSONBody 注解必须填上 value 属性或 name 属性的值，作为JSON的字段名称
     */
    @Post("/test/request/json/body")
    ResponseVo<UserInfo> test05(@JSONBody("name") String name, @JSONBody("password") String password);

    /**
     * 被@JSONBody注解修饰的Map类型参数会被自定解析为JSON字符串
     */
    @Post("/test/request/json/body")
    ResponseVo<UserInfo> test06(@JSONBody Map<String, Object> user);

    /**
     * 被@JSONBody注解修饰的List类型参数会被自定解析为JSON字符串
     */
    @Post("/test/request/json/body/array")
    ResponseVo<List<String>> test07(@JSONBody List<String> usernames);

    @Post(
            url = "/test/request/json/body",
            contentType = "application/json"
    )
    ResponseVo<UserInfo> test08(@Body UserInfo user);

    // ? -------------------------xml请求-------------------
    /**
     * 被@JSONBody注解修饰的参数会根据其类型被自定解析为XML字符串
     * 其修饰的参数类型必须支持JAXB，可以使用JAXB的注解进行修饰
     * 使用@XMLBody注解时可以省略 contentType = "application/xml"属性设置
     */
    @Post("http://localhost:8081/test/request/xml/body")
    String test09(@XMLBody UserInfo user);

    // ? -----------------------二进制数据----------------------

    /**
     * 发送Byte数组类型数据
     */
    @Post(
            url = "/file/testFile1/${filename}",
            contentType = "application/octet-stream"
    )
    String test10(@Body byte[] body, @Var("filename") String filename);

    /**
     * 发送File类型数据
     */
    @Post(
            url = "/file/testFile1/${filename}",
            contentType = "application/octet-stream"
    )
    String test11(@Body File file, @Var("filename") String filename);


    /**
     * 发送输入流类型数据
     */
    @Post(
            url = "/file/testFile1/${filename}}",
            contentType = "application/octet-stream"
    )
    String test12(@Body InputStream inputStream, @Var("filename") String filename);
}
